home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Commun⁄Network / RevRdist Folder / RevRdist / RevRdist src / Bullet Field Mgr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-01-27  |  6.2 KB  |  289 lines  |  [TEXT/KAHL]

  1. /*    ——————————————————————————————————————————————————————————————————
  2.     Filename: Bullet Field Mgr.c
  3.     Dialog field bulleter, written for THINK C 4.0.5
  4.     By Chris Johnson (chrisj@emx.utexas.edu)
  5.     Version of: Thursday, August 8, 1991 2:46 PM
  6.     Modified: Sunday, January 26, 1992 by Dale Talcott
  7.         Handle international character sets
  8.         Use round bullet instead of drawing a variable width rectangle
  9.         Don't blame Mr. Johnson for bugs I introduced.
  10.  
  11.     Distribute freely, but say something nice about the author when
  12.     you use it.  Please send me a copy of any improvements you make
  13.     so they can be incorporated into future versions.
  14.  
  15.     See the included file, "Bullet Field Mgr.h" for documentation.
  16.     ——————————————————————————————————————————————————————————————————    */
  17.  
  18.  
  19. #include "Bullet Field Mgr.h"
  20. #include <GestaltEqu.h>
  21. #include <Script.h>
  22.  
  23.  
  24. typedef struct {
  25.     CQDProcs                Procs;
  26.     CQDProcs                OProcs;
  27.     Boolean                    SMEnabled;
  28.     Boolean                    InUs;
  29.     int                        Count;
  30.     Rect                    BBox[];
  31. } BulletFieldRec, *BulletFieldPtr;
  32.  
  33.  
  34. pascal void    BulletStdText(short ByteCount, Ptr TextBuf, Point Number, Point Denom);
  35. pascal short    BulletStdTxMeas(short ByteCount, Ptr TextBuf,
  36.                     Point *Number, Point *Denom, FontInfo *info);
  37. int    IsBulletField(GrafPtr CurPort, BulletFieldPtr Bull, Boolean);
  38.  
  39. typedef    pascal void (*stdtextp)(short, Ptr, Point, Point);
  40. typedef pascal short (*stdmeasp)(short, Ptr, Point *, Point *, FontInfo *);
  41.  
  42. int BulletFieldCreate(
  43. DialogPtr                Dialog,
  44. int                        NumItems,
  45. int                        FieldCount,
  46. int                        Field1, ...)
  47. {
  48.     int                        Continue;
  49.     GrafPtr                    OrigPort;
  50.     BulletFieldPtr            Bull;
  51.     long                    lp;
  52.  
  53.     Continue = FALSE;
  54.  
  55.     GetPort(&OrigPort);
  56.     SetPort(Dialog);
  57.  
  58.     Bull = (BulletFieldPtr) NewPtr(sizeof(BulletFieldRec) + ((long) sizeof(Rect) * FieldCount));
  59.     if (Bull != NULL) {
  60.         int                        *FieldItem;
  61.         Rect                    *DestBBox;
  62.  
  63.     /*    Determine if Script Manager present */
  64.         lp = 0;
  65.         if (Gestalt(gestaltScriptCount, &lp) == 0 && lp > 0)
  66.             Bull->SMEnabled = true;
  67.         else
  68.             Bull->SMEnabled = false;
  69.         Bull->InUs = false;
  70.  
  71.     /*    Build the field boundary list. */
  72.  
  73.         Bull->Count = FieldCount;
  74.  
  75.         FieldItem = &Field1;
  76.         DestBBox = Bull->BBox;
  77.  
  78.         while (--FieldCount >= 0) {
  79.             short                    Type;
  80.             Handle                    Hand;
  81.  
  82.             GetDItem(Dialog, NumItems + *FieldItem++, &Type, &Hand, DestBBox++);
  83.         }
  84.  
  85.     /*    Install the QuickDraw bottleneck procedures. */
  86.  
  87.         if ((((CGrafPtr) Dialog)->portVersion & 0xC000) != 0)
  88.             SetStdCProcs(&Bull->Procs);
  89.         else
  90.             SetStdProcs((QDProcsPtr) &Bull->Procs);
  91.         Bull->OProcs = Bull->Procs;
  92.         Bull->Procs.textProc = (Ptr) BulletStdText;
  93.         Bull->Procs.txMeasProc = (Ptr) BulletStdTxMeas;
  94.         Dialog->grafProcs = (QDProcsPtr) &Bull->Procs;
  95.  
  96.     /*    Indicate successful installation. */
  97.  
  98.         Continue = TRUE;
  99.     }
  100.  
  101.     ((WindowPeek) Dialog)->refCon = (long) Bull;
  102.  
  103.     SetPort(OrigPort);
  104.  
  105.     return (Continue);
  106. }
  107.  
  108.  
  109. void BulletFieldDispose(Dialog)
  110. DialogPtr                Dialog;
  111. {
  112.     if (((WindowPeek) Dialog)->refCon != 0)
  113.         DisposPtr((Ptr) ((WindowPeek) Dialog)->refCon);
  114.  
  115.     Dialog->grafProcs = NULL;
  116. }
  117.  
  118.  
  119. static pascal void
  120. BulletStdText(ByteCount, TextBuf, Numer, Denom)
  121. short                    ByteCount;
  122. Ptr                        TextBuf;
  123. Point                    Numer;
  124. Point                    Denom;
  125. {
  126.     GrafPtr                    CurPort;
  127.     BulletFieldPtr            Bull;
  128.  
  129.     GetPort(&CurPort);
  130.     Bull = (BulletFieldPtr) ((WindowPeek) CurPort)->refCon;
  131.  
  132.     if (IsBulletField(CurPort, Bull, true))
  133.     {
  134.         int                        i, j;
  135.         short                    ct;
  136.         int                        Width;
  137.         FontInfo                FntInfo;
  138.  
  139.         if (Bull->SMEnabled)
  140.         {
  141.             for (i = j = 0; i < ByteCount; i++)
  142.             {
  143.                 ct = CharByte(TextBuf, i);
  144.                 if (ct == smSingleByte || ct == smFirstByte)
  145.                     j++;
  146.             }
  147.         }
  148.         else
  149.             j = ByteCount;
  150.  
  151.         if (j)
  152.         {
  153.             Bull->InUs = true;
  154.             GetFontInfo(&FntInfo);
  155.             Bull->InUs = false;
  156.             Width = FntInfo.ascent;
  157.             if (Width <= 0)
  158.                 Width = 2;
  159.             else if (Width > 14)
  160.                 Width = 14;
  161.             else
  162.                 Width = Width & ~1;
  163.         }
  164.         
  165.         for (i = 0; i < j; i++)
  166.         {
  167.             Rect                    CharBox;
  168.             
  169.             CharBox.left = CurPort->pnLoc.h;
  170.             CharBox.top = CurPort->pnLoc.v - Width + 1;
  171.             CharBox.right = CharBox.left + Width;
  172.             CharBox.bottom = CharBox.top + Width;
  173.  
  174.             InsetRect(&CharBox, 1, 1);
  175.             FrameOval(&CharBox);
  176.             PaintOval(&CharBox);
  177.             
  178.             Move(Width, 0);
  179.         }
  180.     }
  181.     else
  182.     {
  183.         if (Bull)
  184.             ((stdtextp)(Bull->OProcs.textProc))(ByteCount, TextBuf, Numer, Denom);
  185.         else
  186.             StdText(ByteCount, TextBuf, Numer, Denom);
  187.     }
  188. }
  189.  
  190. static pascal short
  191. BulletStdTxMeas (short ByteCount, Ptr TextBuf,
  192.                     Point *Numer, Point *Denom, FontInfo *info)
  193. {
  194.     GrafPtr                    CurPort;
  195.     BulletFieldPtr            Bull;
  196.  
  197.     GetPort(&CurPort);
  198.     Bull = (BulletFieldPtr) ((WindowPeek) CurPort)->refCon;
  199.     /*
  200.      * Use the system text measure unless in bullet field and
  201.      * not measuring text drawing bullet
  202.      */
  203.     if (IsBulletField(CurPort, Bull, false) && Bull && !Bull->InUs)
  204.     {
  205.         int                        i, j;
  206.         int                        ct;
  207.         int                        Width;
  208.         FontInfo                FntInfo;
  209.  
  210.         if (Bull->SMEnabled)
  211.         {
  212.             for (i = j = 0; i < ByteCount; i++)
  213.             {
  214.                 ct = CharByte(TextBuf, i);
  215.                 if (ct == smSingleByte || ct == smFirstByte)
  216.                     j++;
  217.             }
  218.         }
  219.         else
  220.             j = ByteCount;
  221.         Bull->InUs = true;
  222.         GetFontInfo (&FntInfo);
  223.         Bull->InUs = false;
  224.         Width = FntInfo.ascent;
  225.         if (Width <= 0)
  226.             Width = 2;
  227.         else if (Width > 14)
  228.             Width = 14;
  229.         else
  230.             Width = Width & ~1;
  231.         return Width * j;
  232.     }
  233.     if (Bull)
  234.         return ((stdmeasp)(Bull->OProcs.txMeasProc))(ByteCount, TextBuf, Numer, Denom, info);
  235.     else
  236.         return StdTxMeas (ByteCount, TextBuf, Numer, Denom, info);
  237. }
  238.  
  239. static int IsBulletField(GrafPtr CurPort, BulletFieldPtr Bull, Boolean checkpen)
  240. {
  241.     register int            BulletField;
  242.  
  243.     BulletField = FALSE;
  244.  
  245.     if (Bull != NULL) {
  246.         register int            FieldCount;
  247.         register Rect            *Field;
  248.         register Rect            *Clip;
  249.  
  250.         FieldCount = Bull->Count;
  251.         Field = Bull->BBox;
  252.         Clip = &(*CurPort->clipRgn)->rgnBBox;
  253.  
  254.         while (--FieldCount >= 0)
  255.         {
  256.  
  257.         /*    The field should be bulleted if it is currently within the
  258.             clipRgn of the dialog. */
  259.  
  260.             if (Clip->left >= Field->left && Clip->right <= Field->right) {
  261.  
  262.                 if (Clip->top >= Field->top && Clip->bottom <= Field->bottom) {
  263.  
  264.                     BulletField = TRUE;
  265.                     break;
  266.                 }
  267.             }
  268.  
  269.         /*    The field should also be bulleted if the pen is currently
  270.             located inside it. */
  271.  
  272.             if (checkpen)
  273.             {
  274.                 if (CurPort->pnLoc.h >= Field->left && CurPort->pnLoc.h <= Field->right
  275.                 &&  CurPort->pnLoc.v >= Field->top  && CurPort->pnLoc.v <= Field->bottom)
  276.                 {
  277.                     BulletField = TRUE;
  278.                     break;
  279.                 }
  280.             }
  281.             Field++;
  282.         }
  283.     }
  284.  
  285.     return (BulletField);
  286. }
  287.  
  288.  
  289.